/*
**  gui.c
**  Copyright 2011, Zane Sims
**
**  This file is part of brick-breaker-game.
**
**  brick-breaker-game is free software: you can redistribute it
**  and/or modify it under the terms of the GNU General Public
**  License as published by the Free Software Foundation, either
**  version 3 of the License, or (at your option) any later version.
**
**  brick-breaker-game is distributed in the hope that it will be useful,
**  but WITHOUT ANY WARRANTY; without even the implied warranty of
**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**  GNU General Public License for more details.
**
**  You should have received a copy of the GNU General Public License
**  along with brick-breaker-game.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "gui.h"
#include "common.h"

ClickableSet* new_clickable_set()
{
	ClickableSet *cs = malloc(sizeof(ClickableSet));
	cs->slots = 0;
	cs->clickables = NULL;

	return cs;
}

void free_clickable_set(ClickableSet *cs)
{
	int i = 0;

	if(cs != NULL)
	{
		for(i=0;i<cs->slots;i++)
		{
			if(cs->clickables[i] != NULL)
				free(cs->clickables[i]);
		}

		if(cs->clickables != NULL)
			free(cs->clickables);

		free(cs);
		cs = NULL;
	}
}

void process_clickable_set_clicks(ClickableSet *cs, int mouse_x, int mouse_y)
{
	Clickable *c = NULL; /* temp variable to make cleaner code */
	int i = 0;

	for(i=0; i<cs->slots;i++)
	{
		c = cs->clickables[i];

		if(c!=NULL && c->click!=NULL)
		{
			if(point_in_rect(mouse_x, mouse_y, c->x1, c->y1, c->x2, c->y2))
			{
				c->click(mouse_x, mouse_y, c);
				break;
			}
		}
	}
}

void process_clickable_set_hovers(ClickableSet *cs, int mouse_x, int mouse_y)
{
	Clickable *c = NULL; /* temp variable to make cleaner code */
	int i = 0;

	for(i=0;i<cs->slots;i++)
	{
		c = cs->clickables[i];

		if(c != NULL)
		{
			if(point_in_rect(mouse_x, mouse_y, c->x1, c->y1, c->x2, c->y2)) /* if mouse is on the clickable */
			{
				if(!c->hovering)
				{
					c->hovering = 1;
					
					if(c->hover != NULL)
						c->hover(mouse_x, mouse_y, c, 1);
				}
				//else
				//	break; /* if already hovering over this one, we don't need to check for any more hovers */
			}
			else if(c->hovering)/* if mouse is not on the clickable, but it was previously... */
			{
				c->hovering = 0;

				if(c->hover != NULL)
					c->hover(mouse_x, mouse_y, c, 0);
			}
		}
	}
}

int reg_clickable(Clickable *c)
{
	int i = 0;
	ClickableSet *cs = NULL;

	if(c==NULL || c->parent_set==NULL)
		return 0;

	cs = c->parent_set;

	/* check for an unused clickable slot */
	/* shouldn't cause an error if clickables is NULL because slots should be 0 */
	for(i=0;i<cs->slots;i++)
	{
		if(cs->clickables[i] == NULL)
		{
			cs->clickables[i] = c;
			return 1;
		}
	}

	/* if there wasn't an unused slot, make some more and then use one */
	cs->slots += 5;
	cs->clickables = realloc(cs->clickables, cs->slots*sizeof(Clickable*));

	for(i=cs->slots-4;i<cs->slots;i++)
	{
		cs->clickables[i] = NULL;
	}

	cs->clickables[cs->slots-5] = c;
	return 0;
}

void unreg_clickable(Clickable *c)
{
	ClickableSet *cs = NULL;
	int i = 0;

	if(c!=NULL)
	{
		cs = (ClickableSet*) c->parent_set;

		for(i=0;i<cs->slots;i++)
		{
			if(cs->clickables[i] == c)
			{
				cs->clickables[i] = NULL;
				c = NULL;
				break;
			}
		}
	}
}

void draw_clickable(Clickable *c)
{
	if(c != NULL)
	{
		int width = c->x2 - c->x1;
		int height = c->y2 - c->y1;
		int text_x = 0;
		int text_y = c->y2 - (height/2) - al_get_font_line_height(c->font)/2 - 1;

		if(c->img != NULL)
			al_draw_scaled_bitmap(c->img, 0, 0, al_get_bitmap_width(c->img), al_get_bitmap_height(c->img), c->x1, c->y1, width, height, 0);
		else if(!c->transparent)
			al_draw_filled_rectangle(c->x1, c->y1, c->x2, c->y2, c->back_color);

		/* if there is text to draw */
		if(c->text[0] != '\0')
		{
			if(c->icon != NULL) /* must be left aligned */	text_x = c->x1 + al_get_bitmap_width(c->icon) + 8;
			else if(c->text_align == ALLEGRO_ALIGN_CENTRE)	text_x = c->x2-(width/2);
			else if(c->text_align == ALLEGRO_ALIGN_LEFT)	text_x = c->x1 + 4;
			else if(c->text_align == ALLEGRO_ALIGN_RIGHT)	text_x = c->x2 - 4;

			al_draw_text(c->font, c->text_color, text_x, text_y, c->text_align, c->text);
		}

		if(c->icon != NULL)
			al_draw_bitmap(c->icon, c->x1+4, c->y1 + height/2 - al_get_bitmap_height(c->icon)/2, 0);

		if(c->border_size > 0)
			draw_outside_border(c->x1, c->y1, c->x2, c->y2, c->border_color, c->border_size);
	}
}

void draw_outside_border(int x1, int y1, int x2, int y2, ALLEGRO_COLOR color, int size)
{
	al_draw_filled_rectangle(x1-size, y1-size, x2+size, y1, color);
	al_draw_filled_rectangle(x1-size, y1, x1, y2, color);
	al_draw_filled_rectangle(x2, y1, x2+size, y2, color);
	al_draw_filled_rectangle(x1-size, y2, x2+size, y2+size, color);
}



